home *** CD-ROM | disk | FTP | other *** search
/ Aminet 21 / Aminet 21 (1997)(GTI - Schatztruhe)[!][Oct 1997].iso / Aminet / text / dtp / LabelMerge.lha / LabelMerge.rexx < prev   
Encoding:
OS/2 REXX Batch file  |  1997-08-06  |  44.8 KB  |  1,071 lines

  1. /**************************************************************************/
  2. /*                                                                        */
  3. /*                         LabelMerge v1.02                               */
  4. /*                                                                        */
  5. /*                                                                        */
  6. /*                    Copyright ©1996-1997 by Dick Whiting                */
  7. /*                                                                        */
  8. /*========================================================================*/
  9. /*                                                                        */
  10. /*                                                                        */
  11. /* Report bugs, comments, etc. to:                                        */
  12. /*                                                                        */
  13. /*                   Dick Whiting <dwhiting@europa.com>                   */
  14. /*                                                                        */
  15. /*                          04 August 1997                                */
  16. /*                                                                        */
  17. /**************************************************************************/
  18. /*
  19. $VER: 1.02 Copyright ©1997 by Dick Whiting
  20. $AUTHOR: Dick Whiting
  21. $DESCRIPTION: Create mail-merged labels, postcards, etc.
  22. */
  23.  
  24. OPTIONS RESULTS
  25.  
  26. /* Make sure rexx support is opened */
  27. IF ~SHOW('L','rexxsupport.library') THEN
  28.    CALL ADDLIB('rexxsupport.library',0,-30)
  29.  
  30. ADDRESS 'PAGESTREAM'
  31.  
  32.  
  33. /**************************************************************************/
  34. /*                                                                        */
  35. /*              You may change these variables if necessary               */
  36. /*                                                                        */
  37. /*========================================================================*/
  38. /*                                                                        */
  39. /* prefsfile is used to set the default intitial options, you CAN change  */
  40. /*           this to point to ANY valid path/filename you wish.           */
  41. /*           The path/filename MUST BE ENCLOSED IN QUOTES                 */
  42. /*                                                                        */
  43. /**************************************************************************/
  44.  
  45. prefsfile="PageStream3:scripts/TemplateData/LabelMerge.prefs"
  46.  
  47. /**************************************************************************/
  48. /*                                                                        */
  49. /* Main Logic:                                                            */
  50. /*                                                                        */
  51. /* 1) Setup Preferences - use internal defaults if no prefsfile           */
  52. /* 2) Get Data file, Template file, etc. using requester                  */
  53. /* 3) Calculate number of text blocks, pages, etc. needed                 */
  54. /* 4) Build each text block with the inserted values                      */
  55. /* 5) Return to user for visual inspection and printing                   */
  56. /*                                                                        */
  57. /* CANCELS and errors are handled by jumping to end of each routine if    */
  58. /* the doneselecting flag is set. Did it this way to avoid a zillion      */
  59. /* exit statements scattered throughout the code.                         */
  60. /*                                                                        */
  61. /**************************************************************************/
  62.  
  63. CALL Init
  64. CALL ReadPrefs
  65. CALL GetUserInfo
  66. CALL LoadPGS
  67. CALL OpenData
  68. CALL GetGuides
  69. CALL BldCoords
  70. do while doneselecting=0
  71.    CALL SelectModel
  72.    CALL BldBoxes
  73. end
  74.  
  75. exit 0
  76.  
  77. /**************************************************************************/
  78. /*                                                                        */
  79. /*  Show a nice:) requester for the user. Get the information needed.     */
  80. /*  The initial display includes any values set in the prefs file.        */
  81. /*                                                                        */
  82. /**************************************************************************/
  83. GetUserInfo:
  84.  
  85. allocarexxrequester '"Label Merge Setup"' 400 200
  86. handle.req=result
  87.  
  88. allocarexxlist
  89. delimlist=result     
  90. do i=1 to delimstem.0                       /* load delimiter char list   */
  91.    addarexxlist delimlist delimstem.i
  92. end
  93.  
  94. allocarexxlist
  95. vindlist=result
  96. do i=1 to vindstem.0                        /* load variable indicators   */
  97.    addarexxlist vindlist vindstem.i||'variable'||vindstem.i.1
  98. end
  99.  
  100. edge=10
  101. leftedge=145
  102. cyclen=145
  103. checklen=10
  104. getinfomsg='Select Options and Files - OK when done'   
  105. getinfo=1                                   /* control of requester loop  */
  106.  
  107. addarexxgadget handle.req EXIT 10 180 70 label "_OK"
  108. okhandle=result
  109.  
  110. addarexxgadget handle.req EXIT 320 180 70 label "_Cancel"
  111. cancelhandle=result
  112.  
  113. addarexxgadget handle.req CYCLE leftedge 10 cyclen label '"Field Delimiter:"' BORDER raised LIST delimlist CURRENT defaultdelim
  114. delimhandle=result
  115.  
  116. addarexxgadget handle.req CYCLE leftedge 25 cyclen label '"Variable Format:"' BORDER raised LIST vindlist CURRENT defaultvind
  117. varhandle=result
  118.  
  119. addarexxgadget handle.req CHECKBOX leftedge 40 checklen label '"Automatic Mode:"' labelpos LEFT BORDER raised CHECKED defaultmode
  120. modehandle=result
  121.  
  122. addarexxgadget handle.req CHECKBOX leftedge 55 checklen label '"Watch Me Work:"' labelpos LEFT BORDER raised CHECKED defaultwatchme
  123. refrhandle=result
  124.  
  125. addarexxgadget handle.req STRING edge+300 55 50 label '"Fuzziness"' labelpos LEFT BORDER raised STRING pctvar
  126. pcthandle=result
  127.  
  128. addarexxgadget handle.req STRING edge 95 350 label '"PAGESTREAM file:"' labelpos ABOVELEFT BORDER raised STRING templatefile
  129. temphandle=result
  130.  
  131. addarexxgadget handle.req EXIT edge+355 95 10 label "?"
  132. gettemphandle=result
  133.  
  134. addarexxgadget handle.req STRING edge 125 350 label '"ASCII data file:"' labelpos ABOVELEFT BORDER raised STRING datafile 
  135. datahandle=result
  136.  
  137. addarexxgadget handle.req EXIT edge+355 125 10 label "?"
  138. getdatahandle=result
  139.  
  140. addarexxgadget handle.req TEXT edge 155 380 label '"Label Merge Messages:"' labelpos ABOVELEFT BORDER text STRING '"'getinfomsg'"'
  141. infomsghandle=result
  142.  
  143. addarexxgadget handle.req EXIT 165 180 70 label "_Help"
  144. helphandle=result
  145.  
  146.  
  147. do while getinfo=1
  148.  
  149.    doarexxrequester handle.req
  150.    action=result
  151.  
  152.    getarexxgadget handle.req delimhandle current
  153.    delimchar=result
  154.  
  155.    getarexxgadget handle.req varhandle current
  156.    varchar=result
  157.  
  158.    getarexxgadget handle.req modehandle checked
  159.    modechar=result
  160.  
  161.    getarexxgadget handle.req refrhandle checked
  162.    refrchar=result
  163.  
  164.    getarexxgadget handle.req datahandle string
  165.    datachar=result
  166.    if datachar~=datafile then datafile=datachar
  167.  
  168.    getarexxgadget handle.req pcthandle string
  169.    pctchar=result
  170.  
  171.    getarexxgadget handle.req temphandle string
  172.    tempchar=result
  173.    if tempchar~=templatefile then templatefile=tempchar
  174.  
  175.    getinfomsg='Verify Options and Files - OK when ready'   
  176.    setarexxgadget handle.req infomsghandle STRING "'"getinfomsg"'"
  177.  
  178.    select
  179.      when action=okhandle then do            /* user is all done (maybe) */
  180.          i=varchar+1                        /* needs to base of 1 not 0   */
  181.          lvind=vindstem.i                   /* left variable indicator    */
  182.          rvind=vindstem.i.1                 /* right variable indicator   */
  183.          i=delimchar+1                      /* needs to base of 1 not 0   */
  184.          datadelim=delimstem.i.1            /* set data delimiter charact */
  185.          if modechar=1 then mode='AUTO' 
  186.                        else mode='MANUAL'
  187.          getinfo=0                          /* quit loop (maybe)          */
  188.          if datafile='' then do             /* no data file specified     */
  189.             getinfomsg='You must select an ASCII data file'
  190.             setarexxgadget handle.req infomsghandle STRING "'"getinfomsg"'"
  191.             getinfo=1                       /* continue loop              */
  192.          end
  193.          if templatefile='' then do         /* no PGS template specified  */
  194.             getinfomsg='You must select a PageStream template file'
  195.             setarexxgadget handle.req infomsghandle STRING "'"getinfomsg"'"
  196.             getinfo=1                       /* continue loop              */
  197.          end
  198.          if pctchar~='' & datatype(pctchar,'N'),
  199.             & pctchar <= .5 & pctchar >= 0 then pctvar=pctchar
  200.          else do
  201.             getinfomsg='Fuzziness must be between 0 and .5 inclusive'          
  202.             setarexxgadget handle.req pcthandle STRING pctvar
  203.             setarexxgadget handle.req infomsghandle STRING "'"getinfomsg"'"
  204.             getinfo=1                       /* continue loop              */
  205.          end         
  206.       end
  207.       when action=getdatahandle then do
  208.          getfile title "'Select the ASCII file'" PATH datapath LOAD POSBUTTON "Ok" NEGBUTTON "Cancel"
  209.          if rc=0 then do
  210.             datafile=result
  211.             setarexxgadget handle.req datahandle STRING "'"datafile"'" 
  212.          end
  213.       end
  214.       when action=gettemphandle then do
  215.          getfile title "'Select the PAGESTREAM file'" PATH templatepath LOAD POSBUTTON "Ok" NEGBUTTON "Cancel"
  216.          if rc=0 then do 
  217.             templatefile=result
  218.             setarexxgadget handle.req temphandle STRING "'"templatefile"'"
  219.          end
  220.       end
  221.       when action=cancelhandle then do
  222.          doneselecting=1                    /* user wants to quit         */
  223.          getinfo=0
  224.       end
  225.       otherwise do  /* should be the help button */
  226.          Call HelpDisplay
  227.       end
  228.    end        /* matches select */
  229. end  /* matches do getinfo */
  230.  
  231. freearexxrequester handle.req
  232. freearexxlist delimlist
  233. freearexxlist vindlist 
  234.  
  235. Return
  236.  
  237. /**************************************************************************/
  238. /* Get information about pagesize, margins, and guides                    */
  239. /* Locate ALL guides and store in arrays                                  */
  240. /* Build array describing all possible text block areas and mark the ones */
  241. /*    that are most likely actual label/form text areas.                  */
  242. /**************************************************************************/
  243. GetGuides:
  244.  
  245. if doneselecting=1 then signal GetGuidesExit /* skip all processing       */
  246.  
  247. 'getdimensions diminfo'                     /* get size of paper & orient.*/
  248.  
  249. orient=diminfo.orientation                  /* check orientation of page  */
  250.  
  251. if orient='PORTRAIT' then do
  252.    pgwidth=diminfo.width                    /* width of page              */
  253.    pgheight=diminfo.height                  /* height of page             */
  254. end
  255. else do                                     /* swap them                  */
  256.    pgwidth=diminfo.height                   /* width of page              */
  257.    pgheight=diminfo.width                   /* height of page             */
  258. end
  259.  
  260. 'getmarginguides marinfo'                   /* get margin guide info      */
  261. lmar=marinfo.inside                         /* left edge of first column  */
  262. rmar=marinfo.outside                        /* right edge of last column  */
  263. tmar=marinfo.top                            /* top margin                 */
  264. bmar=marinfo.bottom                         /* bottom margin              */
  265.  
  266. 'getcolumnguides cinfo'                     /* how many columns and gutter*/
  267. colcnt=cinfo.count                          /* number of cols             */
  268. cgut=cinfo.gutter                           /* size of gutter             */
  269.  
  270. 'getguides hinfo horizontal mpg right'      /* get horizontal guide info  */
  271. hcount=result                               /* number of horizontal guides*/
  272.  
  273. 'getguides vinfo vertical mpg right'        /* get vertical guide info    */
  274. vcount=result                               /* number of vertical guides  */
  275.  
  276. usewidth=pgwidth-(lmar+rmar)                /* useable width              */
  277. useheight=pgheight-(tmar+bmar)              /* useable height             */
  278.  
  279. colwidth=(usewidth-((colcnt-1)*cgut))/colcnt  /* width of a columns       */
  280.  
  281. /**************************************************************************/
  282. /*               Build arrays with all hguides and vguides                */
  283. /**************************************************************************/
  284. /*                         Handle the horizontals                         */
  285. /**************************************************************************/
  286.  
  287. hguide.0=0                                   /* init to NO horizontals    */
  288. joff=0                                       /* for pointer control       */
  289.  
  290. if tmar~=0 then do                           /* has a top margin          */
  291.    hguide.1=tmar                             /* store top margin          */
  292.    joff=1                                    /* bump pointer to next      */
  293. end
  294. do i=1 to hcount                             /* assume in order           */
  295.    j=joff+i                                  /* entry to load             */
  296.    k=i-1                                     /* hinfo starts with 0       */
  297.    hguide.j=hinfo.k                          /* load it                   */
  298. end
  299.  
  300. if bmar~=0 then do                           /* we have a bottom margin   */
  301.    j=joff+i                                  /* next entry slot           */
  302.    hguide.j=pgheight-bmar                    /* load it                   */
  303. end
  304.  
  305. hguide.0=j                                   /* save count of horizontals */
  306. hgidcnt=j                                    /* save count of horizontals */
  307.  
  308. /**************************************************************************/
  309. /*                    Handle vertical for columns first                   */
  310. /**************************************************************************/
  311.  
  312. vguide.0=0                                   /* init to NO verticals      */
  313. j=0                                          /* for pointer control       */
  314. voff=0                                       /* offset for first vertical */
  315.  
  316. if lmar~=0 then do                           /* has a left margin         */
  317.    vmargs.1=lmar                             /* store laft margin         */
  318.    voff=lmar                                 /* add in left margin size   */
  319.    j=1                                       /* bump pointer to next      */
  320. end
  321.  
  322. if colcnt~=0 then do                         /* we have column definitions*/
  323.    if cgut~=0 then do i=2 to (colcnt*2)      /* non zero gutters          */
  324.       if i//2=0 then vpos=((i/2)*colwidth)+(((i/2)-1)*cgut)+voff
  325.                 else vpos= ((i-1)/2)*(colwidth+cgut)+voff
  326.       if i/2=colcnt then do                  /* doing last vertical       */
  327.          if rmar~=0 then vpos=pgwidth-rmar   /* use right margin value    */
  328.       end
  329.       j=j+1                                  /* bump to next slot         */
  330.       vmargs.j=vpos                          /* store calculated values   */
  331.       vmargs.0=i                             /* running count of verts    */
  332.    end                                       /* end of ~0 gutter columns  */
  333.    else do
  334.       do i=1 to colcnt                       /* zero gutters between cols */
  335.          vpos=i*colwidth+voff                /* simple;)                  */
  336.          if i=colcnt then do                 /* doing last vertical       */
  337.             if rmar~=0 then vpos=pgwidth-rmar /* use right margin value   */
  338.          end
  339.          j=j+1                               /* bump to next slot         */
  340.          vmargs.j=vpos                       /* store the value           */
  341.       end                                    /* done with zero gutter cols*/
  342.    end                                       /* matches zero gutter else  */
  343. end                                          /* matches colcnt~=0         */
  344.  
  345. vmargs.0=j                                   /* save count for now        */
  346. vgidcnt=j                                    /* save count of verticals   */
  347.  
  348. /**************************************************************************/
  349. /*                 Now handle any vertical guides defined                 */
  350. /*                                                                        */
  351. /* Possible conditions:                                                   */
  352. /*    1) Columns only defined - copy array                                */
  353. /*    2) Vertical page guides only defined  - copy array as is            */
  354. /*       Vertical page guides with margins  - copy array with margins     */
  355. /*    3) Columns AND vertical page guides set - merge the two arrays      */
  356. /*    4) NO verticals set - return with error                             */
  357. /*                                                                        */
  358. /**************************************************************************/
  359.  
  360. j=0                                          /* pointer control           */
  361. select
  362.    when vcount=0 & vgidcnt~=0 then do i=0 to vgidcnt
  363.       vguide.i=vmargs.i
  364.       j=i
  365.    end
  366.    when vcount~=0 & vgidcnt=0 then do i=1 to vcount
  367.       j=j+1
  368.       if i=1 & lmar~=0 then do
  369.          vguide.1=lmar
  370.          j=j+1
  371.       end
  372.       k=i-1
  373.       vguide.j=vinfo.k
  374.       if i=vcount & rmar~=0 then do
  375.          j=j+1
  376.          vguide.j=pagewidth-rmar
  377.       end
  378.    end
  379.    when vcount~=0 & vgidcnt~=0 then do
  380.       Call MergeVerts
  381.    end
  382.    otherwise do
  383.       errmsg='This page has NO vertical guides or margins -- QUITTING'
  384.       Call ErrorDisplay
  385.       doneselecting=1                       /* skip selecting             */
  386.       signal GetGuidesExit                  /* exit from routine          */
  387.    end
  388. end
  389.  
  390. vguide.0=j                                  /* final count of entries     */
  391. vgidcnt=j                                   /* save count of verticals    */
  392.  
  393. GetGuidesExit:
  394.  
  395. Return
  396.  
  397. /**************************************************************************/
  398. /*                   Merge the two vertical info arrays                   */
  399. /**************************************************************************/
  400. MergeVerts:
  401.  
  402. j=1                                         /* ptr for vguide array       */
  403. i=1                                         /* ptr for vmargs array       */
  404. k=0                                         /* ptr for vinfo array        */
  405. kdone=0                                     /* flag for when done         */
  406. idone=0                                     /* flag for when done         */
  407. do loop=1                                   /* loop until leave           */
  408.    select
  409.       when kdone=1 & idone=1 then leave loop  /* all merged - I hope:)    */
  410.       when kdone=1 & idone=0 then do
  411.          vguide.j=vmargs.i
  412.          j=j+1
  413.          i=i+1
  414.          if i>vgidcnt then idone=1
  415.       end
  416.       when kdone=0 & idone=1 then do
  417.          vguide.j=vinfo.k
  418.          j=j+1
  419.          k=k+1
  420.          if k=vcount then kdone=1
  421.       end
  422.       when vmargs.i > vinfo.k then do
  423.          vguide.j=vinfo.k
  424.          j=j+1
  425.          k=k+1
  426.          if k=vcount then kdone=1
  427.       end
  428.       when vinfo.k > vmargs.i then do
  429.          vguide.j=vmargs.i
  430.          j=j+1
  431.          i=i+1
  432.          if i>vgidcnt then idone=1
  433.       end
  434.       otherwise do        /* must be equal - use 1 and bump all pointers */
  435.          vguide.j=vmargs.i
  436.          j=j+1
  437.          i=i+1
  438.          k=k+1
  439.          if i>vgidcnt then idone=1
  440.          if k=vcount then kdone=1
  441.       end
  442.    end
  443. end
  444.  
  445. j=j-1                                       /* remove last increment      */
  446.  
  447. Return
  448.  
  449. /**************************************************************************/
  450. /*         Use guide arrays to build coords of each possible box          */
  451. /*          Mark which ones are true boxes and which are spacers          */
  452. /**************************************************************************/
  453. BldCoords:
  454.  
  455. if doneselecting=1 then signal BldCoordsExit /* skip all processing       */
  456.  
  457. hboxcnt=(vguide.0)-1                        /* number of boxes across     */
  458. vboxcnt=(hguide.0)-1                        /* number of boxes down       */
  459. bguide=hguide.hgidcnt                       /* bottom guide               */
  460. rguide=vguide.vgidcnt                       /* right guide                */
  461.  
  462. /**************************************************************************/
  463. /*       Load array with upper left coords for each box       (ulx,uly)   */
  464. /*       Load array with lower right coord for each box       (lrx,lry)   */
  465. /*       Load array with width and height  for each box       (w,h)       */
  466. /*       Flag each box as being a valid text size block or not (Y/N)      */
  467. /*                                                                        */
  468. /* Format of array: boxdesc.ulx.uly.lrx.lry.widht.height.flag             */
  469. /*                                                                        */
  470. /**************************************************************************/
  471.  
  472. do i=1 to hboxcnt
  473.    do j=1 to vboxcnt
  474.       k=((i-1)*vboxcnt)+j                   /* box being handled          */
  475.       nexth=i+1                             /* next horizontal guide      */
  476.       nextv=j+1                             /* next vertical guide        */
  477.       boxdesc.k=vguide.i                    /* xcoord of top/left corner  */
  478.       boxdesc.k.1=hguide.j                  /* ycoord of top/left corner  */
  479.       if i=hboxcnt then boxdesc.k.1.1=rguide  /* lower right xcoord       */
  480.                    else boxdesc.k.1.1=vguide.nexth
  481.       if j=vboxcnt then boxdesc.k.1.1.1=bguide  /* lower right ycoord     */
  482.                    else boxdesc.k.1.1.1=hguide.nextv
  483.       boxdesc.k.1.1.1.1=boxdesc.k.1.1 - boxdesc.k /* width of box         */
  484.       boxdesc.k.1.1.1.1.1=boxdesc.k.1.1.1 - boxdesc.k.1 /* height of box  */
  485.    end
  486. end
  487.  
  488. boxdesc.0=hboxcnt*vboxcnt                   /* number of possible boxes   */
  489.  
  490. BldCoordsExit:
  491.  
  492. Return
  493.  
  494. /**************************************************************************/
  495. /*                  this is where the boxes are selected                  */
  496. /**************************************************************************/
  497. SelectModel:
  498.  
  499. if doneselecting=1 then signal SelectModelExit
  500.  
  501. if refrchar=0 then do                       /* turn off display updates   */
  502.    'refresh wait'
  503. end
  504.  
  505. if mode='AUTO' then do
  506.    targwidth=boxdesc.1.1.1.1.1              /* width of model box         */
  507.    targheight=boxdesc.1.1.1.1.1.1           /* height of model box        */
  508.    ulx=boxdesc.1                            /* upper left x-coord         */
  509.    uly=boxdesc.1.1                          /* upper left y-coord         */
  510.    midx=ulx+targwidth/2                     /* xcoord middle of object    */ 
  511.    midy=uly+targheight/2                    /* ycoord middle of object    */ 
  512.    'selectobject at ' midx midy             /* select object for id       */
  513. end
  514. else do
  515.    'settoolmode object'                     /* turn on object tool        */
  516.    'getcoord click message "Click in model text frame"'
  517.  
  518.    if rc~=0 then do                         /* user canceled requester    */
  519.       doneselecting=1                       /* set flag                   */
  520.       signal SelectModelExit                /* need to quit               */
  521.    end
  522.  
  523.    'selectobject at ' click.x click.y
  524.  
  525.    'getobject type otype boundingbox selobj'
  526.  
  527.    if ~datatype(otype,'N') then do
  528.       errmsg='You did not select a TEXT FRAME -- QUITTING'
  529.       Call ErrorDisplay
  530.       doneselecting=1                       /* set flag                   */
  531.       signal SelectModelExit                /* need to quit               */
  532.    end
  533.  
  534.    ulx=selobj.left
  535.    uly=selobj.top
  536.    targwidth=selobj.right - selobj.left
  537.    targheight=selobj.bottom - selobj.top
  538. end
  539.  
  540. 'getobject type otype'                      /* get id of this text block  */
  541. objid=result                                /* id is returned in result   */
  542.  
  543. if otype~=11 then do
  544.    errmsg='This is not a text frame -- QUITTING'
  545.    Call ErrorDisplay
  546.    doneselecting=1                          /* set flag                   */
  547.    signal SelectModelExit                   /* need to quit               */
  548. end
  549.  
  550. 'selectobject none'                         /* have to free object        */
  551.  
  552. midx=ulx+targwidth/2                        /* xcoord middle of object    */ 
  553. midy=uly+targheight/2                       /* ycoord middle of object    */ 
  554.  
  555. 'settoolmode text'                          /* change to text mode        */
  556. 'selecttext at 'midx midy                   /* select text in first box   */
  557. 'selecttext at 'midx midy ' all'            /* select text in first box   */
  558. 'getarticlewordcount'                       /* get number of words        */
  559. wordcount=result
  560.  
  561. if wordcount=0 then do
  562.    errmsg='NO text in this block -- QUITTING'
  563.    Call ErrorDisplay
  564.    doneselecting=1                          /* set flag                   */
  565.    signal SelectModelExit                   /* need to quit               */
  566. end
  567.  
  568. 'exporttext file 'importfile 'filter ascii amiga textcode pagestream force'
  569. 'cuttext'                                   /* delete the text            */
  570. 'settoolmode object'                        /* change to object mode      */
  571. 'deleteobject objectid' objid               /* delete the text frame obj  */
  572.  
  573. matchboxes=0                                /* boxes matching model       */
  574.  
  575. do i=1 to boxdesc.0
  576.    testwidth=boxdesc.i.1.1.1.1              /* width of box being tested  */
  577.    testheight=boxdesc.i.1.1.1.1.1           /* height of box being tested */
  578.    widthvar=abs(targwidth-testwidth)/targwidth /* variance in width       */
  579.    heightvar=abs(targheight-testheight)/targheight  /* variance in height */
  580.    if widthvar<=pctvar & heightvar<=pctvar then do
  581.                       boxdesc.i.1.1.1.1.1.1='Y'
  582.                       matchboxes=matchboxes+1 /* one more found           */
  583.                    end
  584.                    else boxdesc.i.1.1.1.1.1.1='N'
  585. end
  586.  
  587. if matchboxes=0 then do                     /* no matches found          */
  588.    errmsg='NO text blocks match Model - QUITTING'
  589.    Call ErrorDisplay
  590.    doneselecting=1                          /* set flag                  */
  591.    signal SelectModelExit                   /* need to quit              */
  592. end
  593.  
  594. SelectModelExit:
  595.  
  596. Return
  597.  
  598. /**************************************************************************/
  599. /*                                                                        */
  600. /* Build all boxes and fill with modified text                            */
  601. /*                                                                        */
  602. /**************************************************************************/
  603. BldBoxes:
  604.  
  605. if doneselecting=1 then signal BldBoxesExit
  606.  
  607. validboxes=0
  608. impstring.=' '
  609. impcnt=0
  610.  
  611. goodopen=open('IMPX',importfile,'R')
  612. if ~goodopen then do
  613.    errmsg='Could not open 'importfile' for input -- QUITTING'
  614.    Call ErrorDisplay
  615.    doneselecting=1                          /* set flag                   */
  616.    signal BldBoxesExit
  617. end   
  618.  
  619. do until eof('IMPX')                        /* read until end of file     */
  620.    impcnt=impcnt+1                          /* next import/export record  */
  621.    impstring.impcnt=readln('IMPX')          /* read next record           */
  622. end                                         /* matches until EOF          */
  623.  
  624. result=close('IMPX')                        /* close the import file      */
  625.  
  626. /**************************************************************************/
  627. /*          This is where we need to control the number of pages          */
  628. /**************************************************************************/
  629.  
  630. pagecnt=datacnt%matchboxes                  /* how many whole pages       */
  631. pagepart=datacnt//matchboxes                /* partial pages              */
  632. if pagepart~=0 then pagecnt=pagecnt+1       /* handle extra records       */
  633. dataptr=0                                   /* initialize data pointer    */
  634.  
  635. openbusyrequester message 'Processing...' thermometer abort enabled total datacnt current 0
  636. bh=result                                   /* pointer to requester       */
  637. bhopen=1                                    /* set a flag for later       */
  638.  
  639. do pagenum=1 to pagecnt                     /* end of loop is within code */
  640.    do i=1 to boxdesc.0                      /* loop thru box definitions  */
  641.       if boxdesc.i.1.1.1.1.1.1='Y' then do  /* need to draw this one      */
  642.          ulx=boxdesc.i
  643.          uly=boxdesc.i.1
  644.          lrx=boxdesc.i.1.1
  645.          lry=boxdesc.i.1.1.1
  646.          'drawcolumn ' ulx uly lrx lry column 1
  647.          validboxes=validboxes+1
  648.          'selecttext at ' ulx uly
  649.          dataptr=dataptr+1
  650.          Call ChangeText
  651.          if doneselecting=1 then signal BldBoxesExit /* something went wrong */
  652.          'inserttext file ' importfile 'filter ascii amiga textcode pagestream'
  653.          getbusyrequester bh                /* test for abort             */
  654.          if result=1 then do
  655.                           doneselecting=1     /* indicate time to quit    */
  656.                           signal BldBoxesExit
  657.                      end
  658.                      else setbusyrequester bh current dataptr
  659.          if dataptr=datacnt then leave pagenum /* all data recs processed */
  660.          if validboxes=matchboxes then do   /* is it end of a full page ? */
  661.             i=999999                        /* force end of boxdesc loop  */
  662.             validboxes=0                    /* reset boxes drawn on page  */
  663.             'Display page next'             /* go to next page            */
  664.          end                                /* matches end of page        */
  665.       end                                   /* matches boxdesc='Y'        */
  666.    end                                      /* matches do i=1 to boxdesc.0*/
  667. end
  668.  
  669. 'Display page 1'                            /* go to page 1               */
  670.  
  671. if mode='AUTO' then do                      /* check mode again           */   
  672.    doneselecting=1                          /* only do once               */
  673. end
  674.  
  675. if refrchar=0 then do                       /* refresh page 1 display     */
  676.    'refresh continue'
  677. end
  678.  
  679. BldBoxesExit:
  680.  
  681. if bhopen=1 then do                         /* busy req is open           */
  682.    closebusyrequester bh                    /* close it                   */
  683.    bhopen=0                                 /* show we closed it          */
  684. end
  685.  
  686. Return
  687.  
  688. /**************************************************************************/
  689. /*                                                                        */
  690. /*         Change copy of exported text, rewrite export file              */
  691. /*        !!! Don't use variable 'i' within this routine !!!              */
  692. /**************************************************************************/
  693. ChangeText:
  694.  
  695. do j=1 to impcnt
  696.    impcopy.j=impstring.j
  697. end
  698.  
  699. /**************************************************************************/
  700. /*                     Here is the actual change code                     */
  701. /*                     (what a lot of work to get here;))                 */
  702. /**************************************************************************/
  703.  
  704. do j=1 to impcnt                            /* loop thru copy of text     */
  705.    do varptr=1 to varcnt
  706.       repvar=varname.varptr                 /* search string              */
  707.       replen=length(repvar)                 /* replacement length         */
  708.       do varloop=1
  709.          varpos=pos(repvar,impcopy.j)       /* look for variable to rep.  */
  710.          if varpos~=0 then do
  711.             repstr1=substr(impcopy.j,1,varpos-1) /* part before variable  */
  712.             repstr2=substr(impcopy.j,varpos+replen) /* part after it      */
  713.             impcopy.j=repstr1||datavar.dataptr.varptr||repstr2
  714.          end
  715.          else leave varloop
  716.       end
  717.    end
  718. end
  719.  
  720. goodopen=open('IMPX',importfile,'W')
  721. if ~goodopen then do
  722.    errmsg='Could not open 'importfile' for output -- QUITTING'
  723.    Call ErrorDisplay
  724.    doneselecting=1                          /* set flags                  */
  725.    Signal ChangeTextExit
  726. end
  727.  
  728. do j=1 to impcnt                            /* write array back to file   */
  729.    foo=writeln('IMPX',impcopy.j)            /* write next record          */
  730. end
  731.  
  732. result=close('IMPX')                        /* close the export file      */
  733.  
  734. ChangeTextExit:
  735.  
  736. Return
  737.  
  738. /**************************************************************************/
  739. /*                                                                        */
  740. /*            Read in the information from the .prefs file                */
  741. /*                                                                        */
  742. /**************************************************************************/
  743. ReadPrefs:
  744.    goodopen=open('Prefs',prefsfile,'R')
  745.    if ~goodopen then do
  746.       errmsg='Could not open Prefs file -- using Defaults'
  747.       Call ErrorDisplay
  748.    end
  749.    else do
  750.       do until eof('Prefs')
  751.          pref=readln('Prefs')
  752.          if pref~=' ' & pref~='#' & pref~='' then do
  753.             if pos('#',pref)~=1 then do
  754.                if pos('#',pref)>2 then do
  755.                   pref=substr(pref,1,pos('#',pref)-1)
  756.                end
  757.                pref=strip(pref)
  758.                interpret pref
  759.             end
  760.          end
  761.       end
  762.    end
  763.    result=close('Prefs')
  764.  
  765. Return
  766.  
  767. /**************************************************************************/
  768. /*                                                                        */
  769. /*                     Load PageStream file                               */
  770. /*                                                                        */
  771. /**************************************************************************/
  772. LoadPGS: 
  773.  
  774. if doneselecting=1 then signal LoadPGSExit  /* error or cancel            */
  775.  
  776. 'open ' "'"templatefile"'"
  777. if rc~=0 then do
  778.    errmsg='Unable to open PageStream file: 'le||le||templatefile
  779.    CALL ErrorDisplay
  780.    doneselecting=1
  781. end
  782.  
  783. LoadPGSExit:
  784.  
  785. Return
  786.  
  787. /**************************************************************************/
  788. /*                                                                        */
  789. /*                     Read the Data file into array                      */
  790. /*                                                                        */
  791. /**************************************************************************/
  792. OpenData:
  793.  
  794. if doneselecting=1 then signal OpenDataExit /* error or cancel            */
  795.  
  796.    varcnt=1                                 /* assume we'll have a header */
  797.    goodopen=open('Data',datafile,'R')
  798.    if ~goodopen then do
  799.       errmsg='Could not open data file: 'le||le||datafile
  800.       Call ErrorDisplay
  801.       doneselecting=1
  802.       signal OpenDataExit
  803.    end
  804.  
  805.    if lvind='<' then do                     /* handle PGS escape coding   */
  806.       lvind='<\<>'
  807.       rvind='<\>>'
  808.    end
  809.  
  810. ReadHeader:
  811.  
  812.    headln=readln('Data')
  813.    delimpos=pos(datadelim,headln)           /* find first delimiter       */
  814.    do while delimpos~=0                     /* loop across header record  */
  815.       rawvar=substr(headln,1,delimpos-1)    /* variable name              */
  816.       rawvar=strip(rawvar)                  /* strip blanks               */
  817.       varname.varcnt=lvind||rawvar||rvind   /* concat with indicators     */
  818.       headln=substr(headln,delimpos+1)      /* shorten remainin data rec  */
  819.       delimpos=pos(datadelim,headln)        /* find next delimiter        */
  820.       varcnt=varcnt+1                       /* increment counter          */
  821.    end
  822.    rawvar=headln                            /* last variable name         */
  823.    rawvar=strip(rawvar)                     /* strip blanks               */
  824.    varname.varcnt=lvind||rawvar||rvind      /* concat with indicators     */
  825.    varname.0=varcnt                         /* store variable count       */
  826.  
  827.    if varcnt=1 & (headln='' | headln=' ') then do  /* no header info      */
  828.       errmsg='NO header found in data file -- QUITTING'
  829.       Call ErrorDisplay
  830.       doneselecting=1
  831.       signal OpenDataExit
  832.    end
  833.  
  834. ReadData:
  835.  
  836.    do until eof('Data')                     /* read until end of file     */
  837.       dataln=readln('Data')                 /* read next record           */
  838.       if dataln~='' then do                 /* skip null records          */
  839.          datacnt=datacnt+1                  /* record count being done    */
  840.          do i=1 to varcnt                   /* parse values from data rec */
  841.             delimpos=pos(datadelim,dataln)  /* location of delimiter char */
  842.             if delimpos~=0 then do          /* found a delimiter          */
  843.                datavar.datacnt.i=substr(dataln,1,delimpos-1)
  844.                dataln=substr(dataln,delimpos+1) /* shorten data record    */
  845.             end
  846.             else do
  847.                datavar.datacnt.i=dataln     /* use remainder of record    */
  848.             end
  849.          end                                /* matches i=1 to varcnt      */
  850.       end                                   /* matches non null record    */
  851.    end                                      /* matches until EOF          */
  852.  
  853.    datavar.0=datacnt                        /* store count of records     */
  854.    result=close('Data')                     /* close the data file        */
  855.  
  856.  
  857. FixData:
  858.  
  859.    do i=1 to datavar.0                      /* loop thru each data record */
  860.       do j=1 to varcnt                      /* for each variable          */
  861.          spos=1                             /* start of string position   */
  862.          tpos=verify(datavar.i.j,'<>@\','MATCH')    /* chars to escape    */
  863.          do while tpos>0                            /* if found escape it */
  864.             datavar.i.j=insert('>',datavar.i.j,spos+tpos-1) 
  865.             datavar.i.j=insert('<\',datavar.i.j,spos+tpos-2)
  866.             spos=spos+tpos+3                /* position after this one    */
  867.             tpos=verify(substr(datavar.i.j,spos),'<>@\','MATCH')      
  868.          end
  869.       end
  870.    end
  871.  
  872.  
  873. OpenDataExit:
  874.  
  875. Return
  876.  
  877. /**************************************************************************/
  878. /*                                                                        */
  879. /*                     Setup variables, lists, etc.                       */
  880. /*                                                                        */
  881. /**************************************************************************/
  882. Init:
  883.  
  884. le=d2c(10)                             /* line end text displaying        */
  885.  
  886. delimstem.0=3                          /* change this if add delimieters  */
  887. delimstem.1='Comma'                    /* name of character               */
  888. delimstem.1.1=','                      /* character itself                */
  889. delimstem.2='Tab' 
  890. delimstem.2.1=d2c(09)
  891. delimstem.3='SemiColon'
  892. delimstem.3.1=';'
  893.  
  894. defaultdelim=0                         /* default data delimiter          */
  895.  
  896. vindstem.0=4     /* number of pairs -- change this if add var indicators  */
  897. vindstem.1='<'                         /* left indicator of pair          */
  898. vindstem.1.1='>'                       /* right indicator of pair         */
  899. vindstem.2='«'                         /* left indicator of pair          */
  900. vindstem.2.1='»'                       /* right indicator of pair         */
  901. vindstem.3='['                         /* left indicator of pair          */
  902. vindstem.3.1=']'                       /* right indicator of pair         */
  903. vindstem.4='{'                         /* left indicator of pair          */
  904. vindstem.4.1='}'                       /* right indicator of pair         */
  905.  
  906. defaultvind=0                          /* default variable indicator      */
  907.  
  908. varname.=' '                           /* initialize var names to blank   */
  909. varname.0=0                            /* initialize variable count to 0  */
  910. varcnt=0                               /* initialize to NO variable names */
  911.  
  912. datavar.=' '                           /* initialize var fields to blanks */
  913. datavar.0=0                            /* initialize record count to zero */
  914. datacnt=0                              /* initialize to NO data records   */
  915.  
  916. pctvar=.10                             /* allow 10% variance in box sizes */
  917.  
  918. mode='AUTO'                            /* default to automatic handling   */
  919. defaultmode="True"                     /* Automatic mode of processing    */
  920.  
  921. defaultwatchme="True"                  /* default to screen refreshing    */
  922.  
  923. datapath='PageStream3:'                /* use PGS3 path for requesters    */
  924. datafile=''                            /* init to missing                 */
  925. templatepath='PageStream3:'            /* use PGS3 path for requesters    */
  926. templatefile=''                        /* init to missing                 */
  927. importfile="T:LabelMerge.import"       /* name of temporary file          */
  928.  
  929. doneselecting=0                        /* haven't finished selections yet */
  930. bhopen=0                               /* no busy requester yet           */
  931.  
  932. errmsg=''                              /* no errors to start with         */
  933.  
  934. /**************************************************************************/
  935. /*        Internal Help Information for Label Merge Program               */
  936. /*                                                                        */
  937. /*        each group can be no longer than 255 characters                 */
  938. /*        this is roughly 6 complete lines of help text                   */
  939. /**************************************************************************/
  940.  
  941. helppages=9                            /* number of pages of help info    */
  942.  
  943.  helpmsg.1='See LabelMerge.readme for complete details'le||le||,
  944. 'Prior to using this script you must create',
  945. 'a PAGESTREAM TEMPLATE file that describes',
  946. 'the label sheet you are going to print.'le||le||,
  947. 'Each print area must be bounded by guides',
  948. 'and have a model text frame defined.'   
  949.  
  950.  helpmsg.2='The text allows variables using any of',
  951. 'these pairs: < >, « », [ ], or { }'le||le||,
  952. 'The « » pair can be produced using',
  953. 'Alt-9 and Alt-0 keys.'le||le'The default indicators',
  954. 'are < >.'le||le'Example: <name> <addr> etc.'le||le||,
  955. 'Only one type is allowed within a single template.'
  956.  
  957.  helpmsg.3='The DATA FILE requires a header with the',
  958. 'variable names separated by the delimiter set in the',
  959. 'FIELD DELIMITER gadget'le||le||,
  960. 'The remaining records contain the data that will replace',
  961. 'the variables in the template'le||le||,
  962. 'Each data field must be separated by the DELIMITER.'
  963.  
  964.  helpmsg.4='The built in options for DELIMITER are:'le||le||,
  965. 'COMMA'le||le||,
  966. 'TAB'le||le||,
  967. 'SEMI-COLON'le||le||,
  968. 'The default is COMMA'
  969.  
  970.  helpmsg.5='The AUTO option expects only ONE text',
  971. 'frame type in the template and that the model is the',
  972. 'TOP LEFT text frame.'le||le||,
  973. 'Turning AUTO OFF allows for multiple sizes of text frames',
  974. 'and for a template that does not match the expected',
  975. 'default.'
  976.  
  977.  helpmsg.6='The WATCH-ME-WORK option shows you all',
  978. 'of the processing as it takes place.'le||le||,
  979. 'Turning it off limits the number of screen refreshes.'le||le||,
  980. 'On my A4000/040 this is about 14% faster.'
  981.  
  982.  helpmsg.7='The FUZZINESS value controls how close',
  983. 'a bounded area must be to the model to be considered as a match.'le||le||,
  984. 'A target must be within this variance in',
  985. 'width and height.'le||le||'The default is .10'                  
  986.  
  987.  helpmsg.8='IN CASE OF EMERGENCY:'le||le||,
  988. 'If you must STOP LabelMerge in the midst of processing'le||le||,
  989. '1) Switch to WorkBench'le||le||,
  990. '2) Open a CLI window'le||le||,
  991. '3) Enter <HI> (without the brackets) and it should quit shortly'
  992.  
  993.  helpmsg.9='For BUG reports, comments, etc.'le||le||,
  994. 'Contact:'le||le||,
  995. 'Dick Whiting'le||le||,
  996. 'email: dwhiting@europa.com'le||le||,
  997. 'If you use and LIKE this effort, my kids would REALLY love a',    
  998. 'postcard from where ever you live'le||le||,
  999. '28590 S. Beavercreek Rd.'le||,
  1000. 'Mulino, Oregon 97042'le||,
  1001. 'USA'
  1002.  
  1003. Return
  1004.  
  1005. /**************************************************************************/
  1006. /*                                                                        */
  1007. /*                           Display HELP information                     */
  1008. /*                                                                        */
  1009. /**************************************************************************/
  1010. HelpDisplay:
  1011.  
  1012. allocarexxrequester '"Label Merge Help Information"' 400 200
  1013. handle.helpreq=result
  1014.  
  1015. addarexxgadget handle.helpreq MULTILINE 10 10 380 160 BORDER none STRING ' '
  1016. helpmsghandle=result
  1017.  
  1018. addarexxgadget handle.helpreq EXIT 10 180 70 label "_More"
  1019. morehandle=result
  1020.  
  1021. addarexxgadget handle.helpreq EXIT 320 180 70 label "_Cancel"
  1022. hcancelhandle=result
  1023.  
  1024. do hshow=1 to helppages
  1025.  
  1026.    setarexxgadget handle.helpreq helpmsghandle STRING '"'helpmsg.hshow'"'
  1027.    
  1028.    if hshow=helppages then do
  1029.       setarexxgadget handle.helpreq morehandle label "_Again"
  1030.    end
  1031.    else do
  1032.       setarexxgadget handle.helpreq morehandle label "_More"
  1033.    end
  1034.  
  1035.    doarexxrequester handle.helpreq
  1036.    haction=result
  1037.  
  1038.    if haction=hcancelhandle then leave hshow
  1039.    if hshow=helppages & haction=morehandle then hshow=0 
  1040.  
  1041. end
  1042.  
  1043. freearexxrequester handle.helpreq
  1044.  
  1045. Return
  1046. /**************************************************************************/
  1047. /*                                                                        */
  1048. /*                          Display ERROR information                     */
  1049. /*                                                                        */
  1050. /**************************************************************************/
  1051. ErrorDisplay:
  1052.  
  1053. errmsg=errmsg||le||le||'See LabelMerge.readme for usage details'            
  1054.  
  1055. allocarexxrequester '"Label Merge ERROR Information"' 400 200
  1056. handle.errreq=result
  1057.  
  1058. addarexxgadget handle.errreq MULTILINE 10 10 380 160 BORDER none STRING '"'errmsg'"'
  1059. errmsghandle=result
  1060.  
  1061. addarexxgadget handle.errreq EXIT 165 180 70 label "_Done"
  1062. donehandle=result
  1063.  
  1064. doarexxrequester handle.errreq
  1065. haction=result
  1066.  
  1067. freearexxrequester handle.errreq
  1068.  
  1069. Return
  1070.  
  1071.